package com.cuijq.datasource;

import java.util.ArrayList;
import java.util.List;

public class ArrayListDemo {

  /**
   * //为什么数组要从 0 开始编号，而不是从 1 开始呢？ // 用 a 来表示数组的首地址，a[0]就是偏移为 0 的位置
   * <p>
   * // 从0开始内存的计算公式，a[k]_address = base_address + k * type_size // 从1开始内存的计算公式，a[k]_address = base_address +
   * (k-1)*type_size
   * <p>
   * // 如果从1开始需要，每次随机访问数组元素都多了一次减法运算，对于 CPU 来说，就是多了一次减法指令 ，性能损耗
   */

  //数组（Array）是一种线性表数据结构。它用一组连续的内存空间，来存储一组具有相同类型的数据。

  //a[i]_address = base_address + i * data_type_size
  //data_type_size 每个元素的大小

  //数组和链表的区别

  //数组支持随机访问，根据下标随机访问的时间复杂度为 O(1)
  public static void main(String[] args) {
//    ArrayList users = new ArrayList(10000);
//    for (
//        int i = 0;
//        i < 10000; ++i) {
//      users.add("xxx");
//    }
    ArrayListDemo demo = new ArrayListDemo();
    List<String> list = demo.createList();
    demo.listPrint(list);
    System.out.println("=====================");
    demo.addFirst(list,"first");
    demo.listPrint(list);
    System.out.println("=====================");
    demo.addLast(list,"last");
    demo.listPrint(list);

    System.out.println("=====================");
    List<String> list1 = demo.createFirst();
    demo.addFirst(list,list1);
    demo.listPrint(list);

    System.out.println("=====================");
    List<String> list2 = demo.createLast();
    demo.addLast(list,list2);
    demo.listPrint(list);

  }

  /**
   * 大多数主流虚拟机采用可达性分析算法来判断对象是否存活，在标记阶段， 会遍历所有 GC ROOTS，将所有 GC ROOTS 可达的对象标记为存活。 只有当标记工作完成后，清理工作才会开始。
   * <p>
   * 不足： 1.效率问题。标记和清理效率都不高，但是当知道只有少量垃圾产生时会很高效。 2.空间问题。会产生不连续的内存空间碎片。
   * <p>
   * 二维数组内存寻址：
   * <p>
   * 对于 m * n 的数组，a [ i ][ j ] (i < m,j < n)的地址为：
   * <p>
   * address = base_address + ( i * n + j) * type_size
   * <p>
   * 另外，对于数组访问越界造成无限循环，我理解是编译器的问题，对于不同的编译器， 在内存分配时，会按照内存地址递增或递减的方式进行分配。 老师的程序，如果是内存地址递减的方式，就会造成无限循环。
   */
  public List<String> createFirst() {
    List<String> list = new ArrayList<>();
    list.add("AFirst");
    list.add("BFirst");
    list.add("CFirst");
    list.add("DFirst");
    list.add("EFirst");
    list.add("FFirst");
    return list;
  }
  public List<String> createLast() {
    List<String> list = new ArrayList<>();
    list.add("ALast");
    list.add("BLast");
    list.add("CLast");
    list.add("DLast");
    list.add("ELast");
    list.add("FLast");
    return list;
  }
  public List<String> createList() {
    List<String> list = new ArrayList<>();
    list.add("A");
    list.add("B");
    list.add("C");
    list.add("D");
    list.add("E");
    list.add("F");
    return list;
  }

  public void listPrint(List<String> list) {
    list.forEach(aa -> System.out.println(aa));
  }

  /**
   * 头插
   *
   * @param list
   * @param addfirst
   * @return
   */
  public List<String> addFirst(List<String> list, String addfirst) {
    list.add(0, addfirst);
    return list;
  }

  /**
   * 尾插
   *
   * @param list
   * @param addLast
   * @return
   */
  public List<String> addLast(List<String> list, String addLast) {
    list.add(addLast);
    return list;
  }

  /**
   * @param list
   * @param addHeads
   * @return
   */
  public List<String> addFirst(List<String> list, List<String> addHeads) {
    list.addAll(0, addHeads);
    return list;
  }

  /**
   * @param list
   * @param addLast
   * @return
   */
  public List<String> addLast(List<String> list, List<String> addLast) {
    list.addAll(addLast);
    return list;
  }
}
